<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' rel='stylesheet' type='text/css' />
    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' rel='stylesheet' type='text/css' />
    <script src='https://struts.apache.org/highlighter/js/shCore.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' type='text/javascript'></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all();
    </script>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>S2-013</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="security-bulletins.html">Security Bulletins</a>&nbsp;&gt;&nbsp;<a href="s2-013.html">S2-013</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">S2-013</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=31818224">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=31818224">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=31818224">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=31818224">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=31818224">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=31818224">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent"><h2 id="S2-013-Summary">Summary</h2>

<p>
</p><p>A vulnerability, present in the <em>includeParams</em> attribute of the <em>URL</em> and <em>Anchor</em> Tag, allows remote command execution</p>

<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Who should read this</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>All Struts 2 developers</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Impact of vulnerability</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>Remote command execution</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Maximum security rating</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>High Critical</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Recommendation</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>Developers should immediately upgrade to <a shape="rect" class="external-link" href="http://struts.apache.org/download.cgi#struts23141">Struts 2.3.14.1</a></p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Affected Software</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> Struts 2.0.0 - Struts 2.3.14 </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Reporter</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> The Struts Team </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>CVE Identifier</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" class="external-link" href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1966" rel="nofollow">CVE-2013-1966</a></p></td></tr></tbody></table></div>

<h2 id="S2-013-Problem">Problem</h2>

<p>Both the <a shape="rect" class="external-link" href="http://struts.apache.org/release/2.3.x/struts2-core/apidocs/org/apache/struts2/components/URL.html"><em>s:url</em></a> and <a shape="rect" class="external-link" href="http://struts.apache.org/release/2.1.x/struts2-core/apidocs/org/apache/struts2/components/Anchor.html"><em>s:a</em></a> tag provide an <em>includeParams</em> attribute. </p>

<p>The main scope of that attribute is to understand whether includes http request parameter or not.  </p>

<p>The allowed values of includeParams are:</p>
<ol><li><em>none</em> - include no parameters in the URL (default)</li><li><em>get</em> - include only GET parameters in the URL</li><li><em>all</em> - include both GET and POST parameters in the URL</li></ol>


<p>A request that included a specially crafted request parameter could be used to inject arbitrary OGNL code into the stack, afterward used as request parameter of an <em>URL</em> or <em>A</em> tag , which will cause a further evaluation. </p>

<p>The second evaluation happens when the URL/A tag tries to resolve every parameters present in the original request.<br clear="none">
This lets malicious users put arbitrary OGNL statements into any request parameter (not necessarily managed by the code) and have it evaluated as an OGNL expression to enable method execution and execute arbitrary methods, bypassing Struts and OGNL library protections.</p>

<h2 id="S2-013-Proofofconcept">Proof of concept</h2>

<ol><li>Open HelloWorld.jsp present in the Struts Blank App and add to one of the url/a tag the following parameter:
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 includeParams="all"
</pre>
</div></div>
Such that the line will be something look like this:
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;s:url id="url" action="HelloWorld" includeParams="all"&gt;
</pre>
</div></div>
(it works also with <em>includeParams="get"</em>).</li><li>Run struts2-blank app</li><li>Open the url: http://localhost:8080/example/HelloWorld.action?fakeParam=%25%7B(%23_memberAccess%5B'allowStaticMethodAccess'%5D%3Dtrue)(%23context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%3Dfalse)(%23writer%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23writer.println('hacked')%2C%23writer.close())%7D<br clear="none">
 (this is the shortened version <a shape="rect" class="external-link" href="http://goo.gl/lhlTl" rel="nofollow">http://goo.gl/lhlTl</a>)</li></ol>


<p>As you will notice, in this case, there is no way to escape/sanitize the fakeParam, since it's not an expected parameter. </p>

<h2 id="S2-013-Solution">Solution</h2>

<p>The OGNLUtil class was changed to deny eval expressions by default. </p>

<div class="confluence-information-macro confluence-information-macro-note"><p class="title">Backward Compatibility</p><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p>In case you need to restore the old behavior, you need to define the following constant, inside your struts configuration (<strong>use it at your own risk</strong>).</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;constant name="struts.ognl.enableOGNLEvalExpression" value="true" /&gt;
</pre>
</div></div>
<p>Please, ensure that:</p>
<ol><li>there are no <em>includeParams</em> with "all" or "get" value</li><li>every parameter which is declared inside the <em>u</em> or <em>a</em> tag come from a sanitized input.</li></ol>
</div></div>

<div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p><strong>It is strongly recommended to upgrade to <a shape="rect" class="external-link" href="http://struts.apache.org/download.cgi#struts23141">Struts 2.3.14.1</a>, which contains the corrected OGNL and XWork library.</strong></p></div></div></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
